<?php
/**
 * FbTestUserUtil v0.1
 * 
 * created by Kfir Ozer (kfirufk@gmail.com)
 * based on https://github.com/lordspace/fbdev
 * 
 * please fill the APP_ID and APP_SECRET fields with the appropriate
 * values for your facebook application.
 * 
 * TODO: add more functionality from https://developers.facebook.com/docs/test_users/
 *       example: changing test user's password and name.
 * 
 */

	define("APP_ID","");
	define("APP_SECRET","");

	require_once 'TestUserDetails.php';

	/**
	 * 
	 * @author ufk
	 *
	 */
	class FbTestUserUtil {
		
		private $_args;
		private $_url;
		private $_ch;
		private $_apiAccessToken;
		private $_testUsers;
		
		/**
		 * fetches and sets app token
		 */
		public function __construct() {
			$this->executeGetToken();
		}
		
		/**
		 * fetch test users from graph api (currently facebook provides a max of 50 test users)
		 * 
		 * @param int $limit - limit of players to fetch
		 */
		public function executeGetUsersList($offset=null,$limit=null) {
			$this->getNewCurl();			
			$this->setCurlGetUsersList($offset,$limit);
			$res=$this->executeCurl();
			$usersArray=json_decode($res,true);
			$this->clearTestUsersArray();
			foreach ($usersArray['data'] as &$testUserArray) {
				$testUser = new TestUserDetails($testUserArray);
				$this->_testUsers[]=$testUser;
			} 
		}
		
		
		/**
		 * fetches a random test user based on predefined range (if range is 50 so 0-49)
		 * @param integer $range
		 * @return TestUserDetails
		 */
		public function executeGetRandomUser($range=50) {
			$this->getNewCurl();
			$randomPos = rand(0,$range-1);
			$this->setCurlGetUsersList($randomPos,1);
			$res=$this->executeCurl();
			$usersArray=json_decode($res,true);
			$this->clearTestUsersArray();
			foreach ($usersArray['data'] as &$testUserArray) {
				$testUser = new TestUserDetails($testUserArray);
				$this->_testUsers[]=$testUser;
			}
			$testUsersCount = count($this->_testUsers);
			if ($testUsersCount != 1) {
				die("_testUsers count ".$testUsersCount." ne 1");
			}				
			return $this->_testUsers[0];
		}
		
		/**
		 * returns a test user class from the array
		 * 
		 * @param integer $offset
		 * @return TestUserDetails
		 */
		public function getUserFromArray($offset=0) {
			return $this->_testUsers[$offset];
		}
		
		/**
		 * clears test users array.
		 */
		private function clearTestUsersArray() {
			$this->_testUsers=array();
		}
		
		
		/**
		 * resets the _args variable to default
		 */
		private function resetArgs() {
			$this->_args = array(
					'grant_type' => 'client_credentials',
					'client_id' => APP_ID,
					'client_secret' => APP_SECRET,
			);
		}
		
		/**
		 * creates a new curl instance and resets args array
		 */
		private function getNewCurl() {
			$this->_ch = curl_init();
			curl_setopt($this->_ch, CURLOPT_POST, true);
			curl_setopt($this->_ch, CURLOPT_HEADER, 0);
			curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($this->_ch, CURLOPT_SSL_VERIFYPEER, false);
			curl_setopt($this->_ch, CURLOPT_SSL_VERIFYHOST, false);
			curl_setopt($this->_ch, CURLOPT_HEADER, false);
			$this->resetArgs();
			
		}
		
		/**
		 * fetches and sets the app token
		 */
		private function executeGetToken() {
			$this->getNewCurl();
			$this->setCurlToken();
			$res=$this->executeCurl(false);
			$data_arr = array();
			parse_str($res, $data_arr);
			$this->_apiAccessToken = $data_arr['access_token'];			
		}		
		
		/**
		 * configure curl to fetch facebook token
		 */
		private function setCurlToken() {
			$this->_url = 'https://graph.facebook.com/oauth/access_token';
			curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $this->_args);			
		}
		
		/**
		 * configure curl to create facebook test user
		 *
		 * @param boolean $appInstalled
		 */
		private function setCurlCreateUser($appInstalled=true) {
			$this->_url = 'https://graph.facebook.com/' . APP_ID . '/accounts/test-users';
			$args['access_token'] = $this->_apiAccessToken;
			$args['installed'] = $appInstalled ? 'true' : 'false'; 
			curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $this->args);
		}
		
		/**
		 * configure curl to delete facebook test user
		 * @param long $user_id
		 */
		
		private function setCurlDeleteUser($user_id) {
			$this->_url = 'https://graph.facebook.com/' . $user_id . '?access_token=' . urlencode($this->_apiAccessToken);
			curl_setopt($this->_ch, CURLOPT_CUSTOMREQUEST, "DELETE");
			curl_setopt($this->_ch, CURLOPT_HTTPGET, true);			
		}
		
		/**
		 * checks if a string validates as a json string
		 * @param string $str
		 */
		private function isJsonString($str) {
			return (strpos($str, '}') !== false);
		}
		
		/**
		 * 
		 * configure curl to get test users list
		 * 
		 * @param integer $limit
		 */
		private function setCurlGetUsersList($offset=null,$limit=null) {
			$this->_url = 'https://graph.facebook.com/' . APP_ID . '/accounts/test-users?access_token=' . urlencode($this->_apiAccessToken)
							.($limit != null ? '&limit='.$limit : '')
							.($offset != null ? '&offset='.$offset : '');
			curl_setopt($this->_ch, CURLOPT_HTTPGET, true);			
		}
		
		
		/**
		 * executes curl based on predefined parameters
		 * 
		 * @param boolean $toValidateJsonString
		 */
		private function executeCurl($toValidateJsonString=true) {
			curl_setopt($this->_ch, CURLOPT_URL, $this->_url);
			$res = curl_exec($this->_ch);
			if ($toValidateJsonString && !$this->isJsonString($res)) {
				die("did not receive a json string from url ".$this->_url."\nstring: ".$res);
			}
			curl_close($this->_ch);
			return $res;
		}
		
		
		
	}
